oo::class create Quote {
    superclass Plugin
    variable RenamedPadWidget QuoteType Language QuoteTag

    constructor {renamedPadWidget quoteType language} {
        set RenamedPadWidget $renamedPadWidget
        set QuoteType $quoteType
        set Language $language
        set QuoteTag [$Language getQuoteTag $quoteType]
    }

    method getQuoteIndicesInPad {} {
        set ret {}
        set indices [$RenamedPadWidget tag range $QuoteTag]
        set id 0; set len [llength $indices]
        if {$len == 0} {return {}}
        # VERBOSE
        while {$id < $len-1} {
            if [expr $id%2] {
                lappend ret [lindex $indices $id]-1c
            } else {
                lappend ret [lindex $indices $id]
            }
            incr id
        }
        # VERBOSE
        if {[$RenamedPadWidget compare end != [lindex $indices end]]} {
            lappend ret [lindex $indices end]-1c
        } else {
            lappend ret end; # text end index
        }
        # put $ret
        return $ret
    }

    method getQuoteIndicesInContent {index content} {
        set ret {}
        foreach ids [regexp -all -inline -indices $QuoteType $content] {
            foreach {id _id} $ids {}
            if ![$Language isEscapedPosition? $content $id] {
                lappend ret $index+${id}c
            }
        }
        return $ret
    }

    method hilightQuoteAfterInsert {index content} {
        set idsInContent [my getQuoteIndicesInContent $index $content]
        if {$idsInContent == {}} { return }

        set idsInPad [my getQuoteIndicesInPad]
        set firstHalf {}; set secondHalf {}
        foreach id $idsInPad {
            if [$RenamedPadWidget compare $id < $index] {
                lappend firstHalf $id
            } else {
                lappend secondHalf $id
            }
        }
        # puts "first: $firstHalf; second:  $secondHalf; content: $idsInContent"

        switch [expr [llength $firstHalf]%2][expr [llength $idsInContent]%2] {
            00 { my hilightQuotes $idsInContent }
            11 { my hilightQuotes [concat [lindex $firstHalf end] $idsInContent $secondHalf] }
            10 { my hilightQuotes [concat [lindex $firstHalf end] $idsInContent [lindex $secondHalf 0]] }
            01 { my hilightQuotes [concat $idsInContent $secondHalf]}
        }
    }

    method hilightQuoteBeforeDelete {from {to {}}} {
        if {$to == {}} {set to $from+1c}
        set firstHalf {}; set secondHalf {}
        # VERBOSE
        set idsInPad [my getQuoteIndicesInPad]
        set i 0
        foreach id $idsInPad {
            if {[$RenamedPadWidget compare $id < $from]} {
                lappend firstHalf $id
            } elseif {[$RenamedPadWidget compare $id >= $to]} {
                lappend secondHalf $id
            } else {
                if {[expr $i%2]} {
                    $RenamedPadWidget tag remove $QuoteTag [lindex $idsInPad $i-1] $id+1c
                } else {
                    $RenamedPadWidget tag remove $QuoteTag $id [lindex $idsInPad $i+1]+1c
                }
            }
            incr i
        }
        # puts "first: $firstHalf; second:  $secondHalf; from: $from; to: $to"

        switch [expr [llength $firstHalf]%2][expr [llength $secondHalf]%2] {
            00 {}
            01 { my hilightQuotes $secondHalf }
            10 { my hilightQuotes [concat [lindex $firstHalf end] $secondHalf] }
            11 { my hilightQuotes [list [lindex $firstHalf end] [lindex $secondHalf 0]] }
        }
    }

    method hilightQuoteBeforeReplace {from to content args} {
        my hilightQuoteBeforeDelete $from $to
    }

    method hilightQuoteAfterReplace {from to content args} {
        my hilightQuoteAfterInsert $from $content
    }

    method hilightQuotes {indices} {
        # puts "hilight indices: $indices"
        set id 0; set len [llength $indices]
        $RenamedPadWidget tag remove $QuoteTag [lindex $indices 0] [lindex $indices end]+1c
        while {$id < $len-1} {
            $RenamedPadWidget tag add $QuoteTag \
                [lindex $indices $id] [lindex $indices $id+1]+1c
            incr id 2
        }
        if {$id < $len} {
            $RenamedPadWidget tag add $QuoteTag [lindex $indices end] end
        }
    }

    method getPluginEvents {} {
        return {
            {afterInsert hilightQuoteAfterInsert}
            {beforeDelete hilightQuoteBeforeDelete}
            {beforeReplace hilightQuoteBeforeReplace}
            {afterReplace hilightQuoteAfterReplace}
        }
    }

    unexport all {*}[info class methods Quote -all]
    export hilightQuoteBeforeDelete hilightQuoteAfterInsert getPluginEvents destroy \
        hilightQuoteAfterReplace hilightQuoteBeforeReplace
}
